package com.jiangjiang.eshop.auth.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiangjiang.eshop.auth.cache.PriorityCacheManager;
import com.jiangjiang.eshop.auth.convert.RoleConvert;
import com.jiangjiang.eshop.auth.dao.RoleMapper;
import com.jiangjiang.eshop.auth.domain.AccountRoleRelationshipEntity;
import com.jiangjiang.eshop.auth.domain.RoleEntity;
import com.jiangjiang.eshop.auth.domain.RolePriorityRelationshipEntity;
import com.jiangjiang.eshop.auth.dto.RoleDTO;
import com.jiangjiang.eshop.auth.dto.RoleQueryPageDTO;
import com.jiangjiang.eshop.auth.dto.RoleSaveDTO;
import com.jiangjiang.eshop.auth.dto.RoleUpdateDTO;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @ClassName RoleService
 * @Description TODO
 * @Author jhw
 * @Date 2021/6/17 21:41
 * @Version 1.0
 **/
@Service
public class RoleService extends ServiceImpl<RoleMapper, RoleEntity> {

    @Autowired
    private RoleConvert roleConvert;
    @Autowired
    private RolePriorityRelationShipService rolePriorityRelationShipService;
    @Autowired
    private AccountRoleRelationshipService accountRoleRelationshipService;
    @Autowired
    private PriorityCacheManager priorityCacheManager;


    /**
     * 角色管理-分页查询
     * @param dto 分页查询dto
     * @return 查询结果
     */
    public Page<RoleDTO> queryForPage(RoleQueryPageDTO dto) {
        Page<RoleEntity> page = new Page<>(dto.getPageNo(), dto.getPageSize(), true);
        LambdaQueryWrapper<RoleEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(dto.getId() != null, RoleEntity::getId, dto.getId())
                .eq(Strings.isNotEmpty(dto.getCode()), RoleEntity::getCode, dto.getCode())
                .like(Strings.isNotEmpty(dto.getName()), RoleEntity::getName, dto.getName())
                .like(Strings.isNotEmpty(dto.getRemark()), RoleEntity::getRemark, dto.getRemark())
                .between(Objects.nonNull(dto.getStartTime()) && Objects.nonNull(dto.getEndTime()),
                        RoleEntity::getGmtCreate, dto.getStartTime(), dto.getEndTime());
        Page<RoleEntity> result = this.getBaseMapper().selectPage(page, queryWrapper);

        return roleConvert.convertPageEntity2DTO(result);
    }

    /**
     * 根据id查询角色
     *
     * @param id 角色id
     * @return 角色DTO
     */
    public RoleDTO queryById(Long id) {
        LambdaQueryWrapper<RoleEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(RoleEntity::getId, id);
        return roleConvert.convertEntity2DTO(this.getOne(wrapper));
    }

    /**
     * 新增
     * @param dto 新增角色DTO
     * @return 处理结果
     */
    public Boolean saveRole(RoleSaveDTO dto) {
        return this.save(roleConvert.convertSaveDTO2Entity(dto));
    }

    /**
     * 角色更新
     * @param dto 跟新角色DTO
     * @return 处理结果
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateRole(RoleUpdateDTO dto) {
        LambdaUpdateWrapper<RoleEntity> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(RoleEntity::getId, dto.getId()).eq(RoleEntity::getCode, dto.getCode())
                .set(RoleEntity::getName, dto.getName()).set(RoleEntity::getRemark, dto.getRemark());

        boolean result = this.update(wrapper);
        if(result) {
            rolePriorityRelationShipService.removeByRoleId(dto.getId());
            List<RolePriorityRelationshipEntity> relations = dto.getRolePriorityRelations().stream().map(relation -> RolePriorityRelationshipEntity.builder()
                    .roleId(dto.getId())
                    .priorityId(relation.getPriorityId())
                    .build()).collect(Collectors.toList());
            rolePriorityRelationShipService.saveBatch(relations);

            // 清空缓存数据
            List<Long> accountIds = accountRoleRelationshipService.queryRelationByRoleId(dto.getId()).stream()
                    .map(AccountRoleRelationshipEntity::getAccountId)
                    .distinct()
                    .collect(Collectors.toList());

            for(Long accountId : accountIds) {
                priorityCacheManager.removeCache(accountId);
            }

        }

        return result;
    }

    /**
     * 角色删除
     * @param id 角色id
     * @return 处理结果
     */
    public Boolean deleteRole(Long id) {

        List<AccountRoleRelationshipEntity> relations = accountRoleRelationshipService.queryRelationByRoleId(id);
        if(relations.size() > 0){
            return false;
        }

        this.getBaseMapper().deleteById(id);
        rolePriorityRelationShipService.removeByRoleId(id);

        // 清空缓存
        List<Long> accountIds = relations.stream().map(AccountRoleRelationshipEntity::getAccountId).collect(Collectors.toList());
        for (Long accountId : accountIds) {
            priorityCacheManager.removeCache(accountId);
        }

        return true;
    }
}
